/** 显示json数据,并点击执行设定的命令的类.
  构造函数参数:
  data: json数据,格式为[[key, value]],如key以'+'开头,表示value是下一层的data,
    另规定key不能以'-'开头
  $table: 由jQuery选定的table,用于显示json数据
  action: 一个双参数函数,action(key, value)指定当一个json数据被点击后的行为
  row_width: 每一行显示的数据个数
  
  by setycyas
  @2022-10-04
**/

class jsonCmd {
  
  constructor(data, $table, action, row_width) {
    this.data = data;
    this.$table = $table;
    this.action = action;
    this.row_width = row_width;
    
    this.path = []; // 数据路径,每进入一个对象类的数据记录一次,空则是根目录
    this.current_data = data; // 当前显示的数据,在进入下一层对象或返回时改变
    
    this.refresh_table();
  }
  
  /* 在current_data中,根据key查找位置与内容,返回[index, value],
     找不到的话index = -1,value = null
  */
  get_current_key(key){
    for(let i = 0;i < this.current_data.length;i++){
      if (this.current_data[i][0] == key)
        return [i, this.current_data[i][1]]
    }
    return [-1, null]
  }
  
  /* 根据this.path,获取应该显示的数据 */
  get_current_data(){
    this.current_data = this.data;
    for(let i = 0;i < this.path.length;i++) 
      this.current_data = this.get_current_key(this.path[i])[1];
  }
  
  /* 进入当前数据中key的对象数据 */
  step_in(key){
    this.path.push(key);
    this.get_current_data();
    this.refresh_table();
  }
  
  /* 返回上一层数据 */
  step_out(){
    this.path.pop();
    this.get_current_data();
    this.refresh_table();
  }
  
  /* 刷新所有的数据点击行为,每次刷新table时都要用
    其中以+开头的是进入下一层数据,以-开头的是返回上一层,
    其余的才是action函数设定的行为.
  */
  refresh_tdClick(){
    this.$table.find('td').click(
      (e)=>{       
        let key = e.target.innerText;
        if (key.substr(0,1) == '+'){
          this.step_in(key);
        }else if (key.substr(0,1) == '-'){
          this.step_out();
        }else {
          this.action(key, this.get_current_key(key)[1]);
        }
      }
    );
  }
  
  /* 根据this.current_data,刷新table的显示数据 */  
  refresh_table(){
    let result = "";
    let index = 0;
    for (let i in this.current_data){
      let key = this.current_data[i][0];
      if (index%this.row_width == 0) result += '<tr>';
      if (key.substr(0,1) == '+')
        result += '<td style="background:#44aa44">'+key+'</td>';
      else
        result += '<td style="background:#aaaaaa">'+key+'</td>';
      if (index%this.row_width == this.row_width-1) result += '</tr>';
      index++;
    }
    if (this.path.length > 0){
      if (index%this.row_width == 0) result += '<tr>';
       result += '<td style="background:#aa4444">-返回</td>';
      if (index%this.row_width == this.row_width-1) result += '</tr>';
      index++;
    }
    this.$table.html(result);
    this.refresh_tdClick();
  }
  
}